/**
 * 查找设置
 */
function scFindSetting(opt){
    var com = scCommon.instance();
    var crEle = com.crEle;

    /**
     * 是否显示替换功能
     */
    var replace = opt && opt.replace === false ? false : true;

    var caseCheck = null;
    var regCheck = null;
    var wholeWordCheck = null;
    
    var findResult = null;
    var findIndex = null;
    var lastFrg = null;
    var lastParam = null;

    var currentPosition = null;

    /**
     * 创建视图
     */
    this.createView = function(option){
        option = option ? option : {};

        var box = crEle("div", "sc-find-setting");

        var row = crEle("div", "sc-find-row");
        var label = crEle("label", "sc-find-label");
        var findInput = crEle("input", "sc-find-input");

        findInput.type = "text";
        label.innerText = "查找内容：";

        row.appendChild(label);
        row.appendChild(findInput);
        box.appendChild(row);

        if(replace){
            row = crEle("div", "sc-find-row");
            label = crEle("label", "sc-find-label");
            var replaceInput = crEle("input", "sc-replace-input");
    
            replaceInput.type = "text";
            label.innerText = "替换为："
    
            row.appendChild(label);
            row.appendChild(replaceInput);
            box.appendChild(row);
        }

        row = crEle("div", "sc-find-row");
        
        caseCheck = crEle("input", "sc-find-checkbox");
        var caseLabel = crEle("label", "sc-find-label");
        
        regCheck = crEle("input", "sc-find-checkbox");
        var regLabel = crEle("label", "sc-find-label");
        
        wholeWordCheck = crEle("input", "sc-find-checkbox");
        var wholeWordLabel = crEle("label", "sc-find-label");

        caseCheck.type = "checkbox";
        regCheck.type = "checkbox";
        wholeWordCheck.type = "checkbox";
        
        caseLabel.innerText = "区分大小写";
        wholeWordLabel.innerText = "全字匹配";
        regLabel.innerText = "正则表达式";

        caseLabel.prepend(caseCheck);
        wholeWordLabel.prepend(wholeWordCheck);
        regLabel.prepend(regCheck);

        row.appendChild(caseLabel);
        row.appendChild(wholeWordLabel);
        row.appendChild(regLabel);
        box.appendChild(row);

        row = crEle("div", "sc-find-row,sc-row-right");
        row.style.marginTop = "12px";

        var btnWidth = "90px";
        
        var nextBtn = crEle("button", "sc-dialog-button");
        var prevBtn = crEle("button", "sc-dialog-button");
        var allBtn = crEle("button", "sc-dialog-button");

        nextBtn.style.width = btnWidth;
        prevBtn.style.width = btnWidth;
        allBtn.style.width = btnWidth;

        nextBtn.innerText = "查找";
        prevBtn.innerText = "上一个";
        allBtn.innerText = "查找全部...";

        row.appendChild(nextBtn);
        row.appendChild(prevBtn);
        row.appendChild(allBtn);

        box.appendChild(row);

        findInput.addEventListener("input", ()=>{
            findResult = null;
        });

        nextBtn.addEventListener("click", ()=>{
            if(!option.triggerListener) return;
            find(findInput.value, "next", option);
        });

        prevBtn.addEventListener("click", ()=>{
            if(!option.triggerListener) return;
            find(findInput.value, "prev", option);
        });

        allBtn.addEventListener("click", ()=>{
            if(!option.triggerListener) return;
            option.listener("openDrawer", {
                direction: "left",
                show: true
            }, {
                embed: true,
                listener: option.listener,
                component: new scNavView()
            });
        });

        if(replace){
            row = crEle("div", "sc-find-row,sc-row-right");

            var replaceBtn = crEle("button", "sc-dialog-button");
            var replaceAllBtn = crEle("button", "sc-dialog-button");

            replaceBtn.innerText = "替换";
            replaceAllBtn.innerText = "替换全部";

            replaceBtn.style.width = btnWidth;
            replaceAllBtn.style.width = btnWidth;

            row.appendChild(replaceBtn);
            row.appendChild(replaceAllBtn);

            replaceBtn.addEventListener("click", ()=>{
                if(!option.triggerListener) return;
                option.triggerListener(findInput.value, {
                    type: "current",
                    replaceExp: replaceInput.value
                });
            });
    
            replaceAllBtn.addEventListener("click", ()=>{
                if(!option.triggerListener) return;
                option.triggerListener(findInput.value, {
                    type: "all",
                    value: replaceInput.value
                });
            });
        }

        box.appendChild(row);

        return box;
    }

    /**
     * 查找
     * @param {*} value 
     * @param {*} type 
     * @param {*} option 
     */
    var find = function(value, type, option){
        let pageRange = [];

        if(lastFrg){
            for(let i in lastFrg){
                delete lastFrg[i].highlight;
                if(pageRange.indexOf(lastFrg[i].offset.pageIndex) < 0){
                    pageRange.push(lastFrg[i].offset.pageIndex);
                }
            }
            lastFrg = null;
        }

        var newParam = {
            type: type,
            useReg: regCheck.checked,
            caseSensitive: caseCheck.checked,
            wholeWord: wholeWordCheck.checked
        };

        if(!findResult || !compareParam(lastParam, newParam)){
            let result = option.listener("find", value, newParam);
            parseFindResult(result);
            findIndex = -1;
            lastParam = newParam;
        }

        if(currentPosition){
            let index = getFindIndexByCurrentPosition(type);
            if(index != null){
                findIndex = index;
            }
            currentPosition = null;
        }else{
            if(type == "next"){
                findIndex++;
                findIndex = findIndex >= findResult.length ? findIndex - 1 : findIndex;
            }else if(type == "prev"){
                findIndex--;
                findIndex = findIndex < 0 ? 0 : findIndex;
            }
        }

        let boundRect = null;

        lastFrg = findResult[findIndex];
        if(!lastFrg) return;
        for(let i = 0; i < lastFrg.length; i++){
            lastFrg[i].highlight = true;
            if(pageRange.indexOf(lastFrg[i].offset.pageIndex) < 0){
                pageRange.push(lastFrg[i].offset.pageIndex);
            }
            if(i == lastFrg.length - 1){
                boundRect = {...lastFrg[i].boundRect}
            }
        }

        option.listener("find", null, {
            type: type,
            highlightFindZone: true,
            pageRange: pageRange,
            lastBoundRect: boundRect
        });
    }

    /**
     * 比较参数是否相等
     * @param {*} oldParam 
     * @param {*} newParam 
     * @returns 
     */
    var compareParam = function(oldParam, newParam){
        return oldParam.useReg === newParam.useReg &&
            oldParam.caseSensitive === newParam.caseSensitive &&
            oldParam.wholeWord === newParam.wholeWord; 
    }

    /**
     * 解析查找结果
     * @param {*} result 
     */
    var parseFindResult = function(result){
        findResult = [];

        for(var i in result.fragments){
            if(result.fragments[i].length == 0) continue;
            parsePosition(result.fragments[i], findResult);
        }
    }

    /**
     * 按部位解析查找结果
     * @param {*} position 
     * @param {*} findResult 
     */
    var parsePosition = function(position, findResult){
        let frg = null;
        let index = findResult.length - 1;

        for(let i in position){
            for(let j in position[i]){
                frg = position[i][j];
                if(frg.findStart){
                    index++;
                    findResult[index] = [];
                }
                findResult[index].push(frg);
            }
        }
    }

    /**
     * 根据当前位置获取查找序号
     * @returns 
     */
    var getFindIndexByCurrentPosition = function(type){
        if(!findResult) return;

        let fr = null;
        let f = null;

        if(type == "prev"){
            for(let i = findResult.length - 1; i >=0; i--){
                fr = findResult[i];
                for(let j in fr){
                    f = fr[j];
    
                    if(f.offset.pageIndex < currentPosition.pageIndex){
                        return i;
                    }else if(f.offset.pageIndex > currentPosition.pageIndex){
                        continue;
                    }
    
                    if(f.offset.rowIndex < currentPosition.rowIndex){
                        return i;
                    }else if(f.offset.rowIndex > currentPosition.rowIndex){
                        continue;
                    }
    
                    if(f.offset.elementIndex < currentPosition.elementIndex){
                        return i;
                    }else if(f.offset.elementIndex > currentPosition.elementIndex){
                        continue;
                    }
    
                    if(f.offset.end <= currentPosition.contentIndex){
                        return i;
                    }
                }
            }
        }else{
            for(let i in findResult){
                fr = findResult[i];
                for(let j in fr){
                    f = fr[j];
    
                    if(f.offset.pageIndex > currentPosition.pageIndex){
                        return i;
                    }else if(f.offset.pageIndex < currentPosition.pageIndex){
                        continue;
                    }
    
                    if(f.offset.rowIndex > currentPosition.rowIndex){
                        return i;
                    }else if(f.offset.rowIndex < currentPosition.rowIndex){
                        continue;
                    }
    
                    if(f.offset.elementIndex > currentPosition.elementIndex){
                        return i;
                    }else if(f.offset.elementIndex < currentPosition.elementIndex){
                        continue;
                    }
    
                    if(f.offset.end >= currentPosition.contentIndex){
                        return i;
                    }
                }
            }
        }

        return null;
    };

    /**
     * 接收通知
     * @param {*} eventType 
     * @param {*} option 
     */
    this.notify = function(eventType, option){
        if(eventType == "mousedown"){
            currentPosition = option ? option.offset : null;
        }else if(eventType == "contentChange"){
            findResult = null;
        }
    }
}